package org.mika.asm;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

final class PrivateFieldsFactory implements MethodInterceptor {
	private PrivateFieldsFactory() {}
	

	@SuppressWarnings("unchecked")
	private static <T, I> Class<? extends I> createImplementator(
			Class<T> original,
			Class<? extends T> opener,
			Class<I> interf 
	) {
		Enhancer e = new Enhancer();		
		e.setStrategy(new FieldsImplGenerator<T, I>(original, opener, interf));
		e.setCallbackType(PrivateFieldsFactory.class);
		e.setUseCache(false);
		e.setUseFactory(false);
		return e.createClass();
	}
	
	@SuppressWarnings("unchecked")
	public static <T,I> Class<? extends I> createClass(Class<T> c, Class<I> i) {		
		Enhancer e = new Enhancer();
		e.setStrategy(new FieldsOpenerGenerator(c, i));
		e.setCallbackType(PrivateFieldsFactory.class);
		e.setUseCache(false);
		e.setUseFactory(false);
		return createImplementator(c, e.createClass(), i);			
	}
	
	@SuppressWarnings("unchecked")
	private static <T,I> I createStaticImplementator(
		Class<? extends T> opener, Class<I> interf
	) throws Exception {
		System.err.println("Here");
		Enhancer e = new Enhancer();
		e.setStrategy(new StaticFieldsImplGenerator( opener, interf ));
		e.setCallbackType(PrivateFieldsFactory.class);
		e.setUseCache(false);
		e.setUseFactory(false);
		return (I) e.createClass().newInstance();
	}
	
	@SuppressWarnings("unchecked")
	public static <T,I> I createStaticAccessor(Class<T> c, Class<I> i) throws Exception {
		Enhancer e = new Enhancer();
		e.setStrategy(new StaticFieldsOpenerGenerator(c, i));
		e.setCallbackType(PrivateFieldsFactory.class);
		e.setUseCache(false);
		e.setUseFactory(false);				
		return createStaticImplementator((Class<? extends T>)e.createClass(), i);
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		return null;
	}
}
